+function ($) {
    'use strict';

    var autorefreshTimer

    var Zuiajax = function(element, options) {
        var $this     = this

        this.$element = $(element)
        this.options  = options
        this.tools    = this.TOOLS()
    }

    Zuiajax.DEFAULTS = {
        okalert     : true,
        reload      : true,
        loadingmask : true
    }

    Zuiajax.NAVTAB = 'navtab'

    Zuiajax.prototype.TOOLS = function() {
        var that  = this
        var tools = {
            getPagerForm: function($parent, args, form) {
                var pageInfo = $.extend({}, $.zui.pageInfo)

                if (!form)
                    form = $parent.find('#pagerForm:first')[0]

                if ($parent.data('zui.clientPaging')) {
                    args = $.extend({}, $parent.data('zui.clientPaging'), args)
                    $parent.data('zui.clientPaging', args)
                }

                if (form) {
                    for (var key in pageInfo) {
                        var val = ''

                        if (args && args[key]) val = args[key]
                        if (!form[pageInfo[key]]) $('<input type="hidden" name="'+ pageInfo[key] +'" value="'+ val +'">').appendTo($(form))
                        else if (val) form[pageInfo[key]].value = val
                    }
                }

                return form
            },
            getTarget: function() {
                if (that.$element.closest('.navtab-panel').length) return Zuiajax.NAVTAB
                else return 'dialog'
            }
        }

        return tools
    }

    Zuiajax.prototype.ajaxdone = function(json) {
        if (json[$.zui.keys.status] == $.zui.statusCode.error) {
            if (json[$.zui.keys.message]) $.zui.alertmsg('error', json[$.zui.keys.message])
        } else {
            if (json[$.zui.keys.message]) $.zui.alertmsg('correct', json[$.zui.keys.message])
        }
    }

    Zuiajax.prototype.ajaxerror = function(xhr, ajaxOptions, thrownError) {
        var msg = xhr.responseText, that = this, options = that.options, failCallback = options.failCallback;
        if(that.$target) {
            that.$target.trigger('zui.ajaxError');
        } else if (that.$element) {
            that.$element.trigger('zui.ajaxError');
        }
        if (typeof msg === 'string' && msg.startsWith('{')) {
            this.ajaxdone(msg.toObj())
        } else {
            $.zui.alertmsg('error', '<div>Http status: ' + xhr.status + ' ' + xhr.statusText + '</div>'
                + '<div>ajaxOptions: '+ ajaxOptions +' </div>'
                + '<div>thrownError: '+ thrownError +' </div>'
                + '<div>'+ msg +'</div>')
        }

        if (failCallback) {
            if (typeof failCallback === 'string')
                failCallback = failCallback.toFunc()
            if (typeof failCallback === 'function')
                failCallback.apply(that, [msg, options])
            else
                $.zui.debug('The callback function \'failCallback\' is incorrect: '+ failCallback)
        }
    }

    Zuiajax.prototype.ajaxcallback = function(json) {
        var that = this, options = that.options,
            okCallback = options.okCallback, errCallback = options.errCallback, okAfterCallback = options.okAfterCallback,
            tabids = [], dialogids = [], divids = [], datagrids = []

        var okFunc = function() {
                if (typeof okCallback === 'string')
                    okCallback = okCallback.toFunc()
                if (typeof okCallback === 'function')
                    okCallback.apply(that, [json, options])
                else
                    $.zui.debug('The callback function \'okCallback\' is incorrect: '+ okCallback)
            },
            okAfterFunc = function() {
                if (typeof okAfterCallback === 'string')
                    okAfterCallback = okAfterCallback.toFunc()
                if (typeof okAfterCallback === 'function')
                    okAfterCallback.apply(that, [json, options])
                else
                    $.zui.debug('The callback function \'okAfterCallback\' is incorrect: '+ okAfterCallback)
            },
            errFunc = function() {
                if (typeof errCallback === 'string')
                    errCallback = errCallback.toFunc()
                if (typeof errCallback === 'function')
                    errCallback.apply(that, [json, options])
                else
                    $.zui.debug('The callback function \'errCallback\' is incorrect: '+ errCallback)
            }

        if (typeof json === 'string')
            json = json.toObj()

        if (options.okalert)
            that.ajaxdone(json)

        if (!json[$.zui.keys.status]) {
            if (okCallback) {
                okFunc()
                return
            }
        }
        if (json[$.zui.keys.status] == $.zui.statusCode.ok) {
            if (okCallback) {
                okFunc()
                return
            }

            if (json.tabid)
                $.merge(tabids, json.tabid.split(','))
            if (options.tabid)
                $.merge(tabids, options.tabid.split(','))

            if (json.dialogid)
                $.merge(dialogids, json.dialogid.split(','))
            if (options.dialogid)
                $.merge(dialogids, options.dialogid.split(','))

            if (json.divid)
                $.merge(divids, json.divid.split(','))
            if (options.divid)
                $.merge(divids, options.divid.split(','))

            if (json.datagrid)
                $.merge(datagrids, json.datagrid.split(','))
            if (options.datagrid)
                $.merge(datagrids, options.datagrid.split(','))

            // refresh
            if (tabids.length) {
                $.unique(tabids)
                setTimeout(function() { $.zui.navtab('reloadFlag', tabids.join(',')) }, 100)
            }
            if (dialogids.length) {
                $.unique(dialogids)
                setTimeout(function() { $.zui.dialog('refresh', dialogids.join(',')) }, 100)
            }
            if (divids.length) {
                $.unique(divids)
                setTimeout(function() { that.refreshdiv(divids.join(',')) }, 100)
            }
            if (datagrids.length) {
                setTimeout(function() {
                    $.each(datagrids, function(i, n) {
                        $('#'+ n.trim()).datagrid('refresh')
                    })
                }, 100)
            }

            if (that.$target == $.CurrentNavtab) {
                that.navtabcallback(json)
            } else if (that.$target == $.CurrentDialog) {
                that.dialogcallback(json)
            } else {
                that.divcallback(json)
            }

            if (okAfterCallback) {
                okAfterFunc()
            }
        } else {
            if (errCallback) {
                errFunc()
            }
        }
    }

    Zuiajax.prototype.divcallback = function(json, $target, options) {
        var that = this, options = that.options,
            forward = json.forward || options.forward || null,
            forwardConfirm = json.forwardConfirm || options.forwardConfirm || null


        if (options.reload && !forward) {
            that.refreshlayout(options)
        }

        if (options.reloadNavtab)
            setTimeout(function() { $.zui.navtab('refresh') }, 100)

        if (forward) {
            var _forward = function() {
                $.extend(options, {url: forward})
                that.refreshlayout(options)
            }

            if (forwardConfirm) {
                $.zui.alertmsg('confirm', forwardConfirm, {
                    okCall: function() { _forward() }
                })
            } else {
                _forward()
            }
        }
    }

    Zuiajax.prototype.navtabcallback = function(json) {
        var that = this, options = that.options,
            closeCurrent = json.closeCurrent || options.closeCurrent || false,
            forward = json.forward || options.forward || null,
            forwardConfirm = json.forwardConfirm || options.forwardConfirm || null

        if (closeCurrent && !forward)
            $.zui.navtab('closeCurrentTab')
        else if (options.reload && !forward)
            setTimeout(function() { $.zui.navtab('refresh') }, 100)

        if (forward) {
            var _forward = function() {
                $.zui.navtab('reload', {url:forward})
            }

            if (forwardConfirm) {
                $.zui.alertmsg('confirm', forwardConfirm, {
                    okCall: function() { _forward() },
                    cancelCall: function() { if (closeCurrent) { $.zui.navtab('closeCurrentTab') } }
                })
            } else {
                _forward()
            }
        }
    }

    Zuiajax.prototype.dialogcallback = function(json) {
        var that = this, options = that.options,
            closeCurrent = json.closeCurrent ||json.url=='close' || options.closeCurrent || false,
            forward = json.forward || options.forward || null,
            forwardConfirm = json.forwardConfirm || options.forwardConfirm || null

        if (closeCurrent && !forward)
            $.zui.dialog('closeCurrent')
        else if (options.reload && !forward)
            setTimeout(function() { $.zui.dialog('refresh') }, 100)

        if (options.reloadNavtab)
            setTimeout(function() { $.zui.navtab('refresh') }, 100)
        if (forward) {
            var _forward = function() {
                $.zui.dialog('reload', {url:forward})
            }

            if (forwardConfirm) {
                $.zui.alertmsg('confirm', json.forwardConfirm, {
                    okCall: function() { _forward() },
                    cancelCall: function() { if (closeCurrent) { $.zui.dialog('closeCurrent') } }
                })
            } else {
                _forward()
            }
        }
    }

    Zuiajax.prototype.pagecallback = function(options, target) {
        var that    = this
        var op      = $.extend({}, Zuiajax.DEFAULTS, options)
        var $target = target || null
        var form    = null

        if ($target && $target.length) {
            form = that.tools.getPagerForm($target, op)
            if (form) {
                $.extend(op, $(form).data())
                that.reloadlayout({target:$target[0], type:$(form).attr('method') || 'POST', url:$(form).attr('action'), data:$(form).serializeArray(), loadingmask:op.loadingmask})
            }
        } else {
            if (that.tools.getTarget() == Zuiajax.NAVTAB) {
                $target = $.CurrentNavtab
                form    = that.tools.getPagerForm($target, op)
                if (form) $.extend(op, $(form).data())
                that.$element.navtab('reloadForm', false, op)
            } else {
                $target = $.CurrentDialog
                form    = that.tools.getPagerForm($target, op)
                if (form) $.extend(op, $(form).data())
                that.$element.dialog('reloadForm', false, op)
            }
        }
    }

    Zuiajax.prototype.doajax = function(options) {
        var that = this, $target, $element = that.$element

        if (!options) options = {}
        if (!options.loadingmask) options.loadingmask = false

        options = $.extend({}, Zuiajax.DEFAULTS, typeof options === 'object' && options)
        that.options = options

        if (options.target) {
            if (options.target instanceof jQuery)
                $target = options.target
            else
                $target = $(options.target)
        } else {
            if ($element[0] !== $('body')[0]) {
                $target = $element.closest('.zui-layout')
            }
        }

        if (!$target || !$target.length)
            $target = $.CurrentDialog || $.CurrentNavtab
        if(!$target) $target = $('<body>');
        that.$target = $target

        if (!options.url) {
            $.zui.debug('Zuiajax Plugin: \'doajax\' method: the url is undefined!')
            return
        } else {
            options.url = decodeURI(options.url).replacePlh($target)

            if (!options.url.isFinishedTm()) {
                $.zui.alertmsg('error', (options.warn || $.zui.regional.plhmsg))
                $.zui.debug('Zuiajax Plugin: \'doajax\' method: The url is incorrect: '+ options.url)
                return
            }

            options.url = encodeURI(options.url)
        }

        var callback = options.callback && options.callback.toFunc()
        var todo     = function() {
            if (!options.callback)
                options.callback = $.proxy(function(data) {that.ajaxcallback(data)}, that)

            $target.doAjax(options)
        }

        if (options.confirmMsg) {
            $.zui.alertmsg('confirm', options.confirmMsg,
                {
                    okCall : function() {
                        todo()
                    }
                }
            )
        } else {
            todo()
        }
    }

    Zuiajax.prototype.ajaxform = function(option) {
        var that      = this,
            options   = $.extend({}, typeof option === 'object' && option),
            $element  = that.$element,
            $target   = null,
            $form     = null,
            callback  = options.callback,
            enctype

        // form
        if ($element[0] === $('body')[0]) {
            $form = options.form

            if (!($form instanceof jQuery))
                $form = $(options.form)
        } else {
            $form   = $element
            $target = $form.closest('.zui-layout')
        }

        if (!$form || !$form.length || !($form.isTag('form'))) {
            $.zui.debug('Zuiajax Plugin: \'ajaxform\' method: Not set the form!')
            return
        }

        enctype = $form.attr('enctype')

        // target
        if (options.target) {
            $target = options.target

            if (!($target instanceof jQuery))
                $target = $($target)
        }

        if (!$target || !$target.length)
            $target = $.CurrentDialog || $.CurrentNavtab

        that.$target = $target

        options.url  = options.url || $form.attr('action')
        // for ie8
        if ($.zui.isIE(8) && !options.type) {
            if (!$form[0].getAttributeNode('method').specified) options.type = 'POST'
        }
        options.type = options.type || $form.attr('method') || 'POST'

        $.extend(that.options, options)

        if (callback) callback = callback.toFunc()

        var successFn = function(data, textStatus, jqXHR) {
            callback ? callback.apply(that, [data, $form]) : $.proxy(that.ajaxcallback(data), that)
        }
        var _submitFn = function() {
            var op = {
                loadingmask:that.options.loadingmask,
                type:that.options.type,
                url:that.options.url,
                callback:successFn,
                error:$.proxy(that.ajaxerror, that)
            };

            if (enctype && enctype == 'multipart/form-data') {
                if (window.FormData) {
                    $.extend(op, {data:new FormData($form[0]), contentType:false, processData:false})
                } else {
                    $.extend(op, {data:$form.serializeArray(), files:$form.find(':file'), iframe:true, processData:false})
                }
            } else {
                $.extend(op, {data:$form.serializeArray()})
            }

            if (that.options.ajaxTimeout) op.ajaxTimeout = that.options.ajaxTimeout

            $form.doAjax(op)
        }

        if (that.options.confirmMsg) {
            $.zui.alertmsg('confirm', that.options.confirmMsg, {okCall: _submitFn})
        } else {
            _submitFn()
        }
    }

    Zuiajax.prototype.ajaxsearch = function(option) {
        var that = this, options = $.extend({}, typeof option === 'object' && option), $element = that.$element, form = null, op = {pageCurrent:1}, $form, $target, isValid = options.isValid

        if (options.target) $target = $(options.target)
        if ($element[0] === $('body')[0]) {
            $form = options.form

            if (!($form instanceof jQuery)) {
                $form = $(options.form)
            }
            if (!$form || !$form.length || !($form.isTag('form'))) {
                $.zui.debug('Zuiajax Plugin: \'ajaxsearch\' method: Not set the form!')
                return
            }
            if (options.target) {
                $target = options.target

                if (!($target instanceof jQuery))
                    $target = $($target)
            } else {
                $target = $form.closest('.zui-layout')
            }

            if (!$target || !$target.length)
                $target = $.CurrentDialog || $.CurrentNavtab
        } else {
            $form   = $element
            $target = $form.closest('.zui-layout')

            if (!($form.isTag('form'))) {
                $.zui.debug('Zuiajax Plugin: \'ajaxsearch\' method: Not set the form!')
                return
            }
            if (!$target || !$target.length) {
                $target = $.CurrentDialog || $.CurrentNavtab
            }

            if (!options.url)
                options.url = $form.attr('action')
        }

        that.$target = $target

        if (!options.url)
            options.url = $form.attr('action')

        if (!options.url) {
            $.zui.debug('Zuiajax Plugin: \'ajaxsearch\' method: The form\'s action or url is undefined!')
            return
        } else {
            options.url = decodeURI(options.url).replacePlh($form.closest('.unitBox'))

            if (!options.url.isFinishedTm()) {
                $.zui.alertmsg('error', (options.warn || $.zui.regional.plhmsg))
                $.zui.debug('Zuiajax Plugin: \'ajaxsearch\' method: The form\'s action or url is incorrect: '+ options.url)
                return
            }

            options.url = encodeURI(options.url)
        }

        if (!options.type)
            options.type = $form.attr('method') || 'POST'

        that.tools.getPagerForm($target, op, $form[0])
        options.form = $form

        $.extend(that.options, options)

        var search = function() {
            if ($target.hasClass('zui-layout')) {
                var data = $form.serializeJson(), _data = {}

                if (options.clearQuery) {
                    var pageInfo = $.zui.pageInfo

                    for (var key in pageInfo) {
                        _data[pageInfo[key]] = data[pageInfo[key]]
                    }

                    data = _data
                }

                that.reloadlayout({target:$target[0], type:that.options.type, url:that.options.url, data:data, loadingmask:that.options.loadingmask})
            } else {
                if ($target[0] === ($.CurrentNavtab)[0]) {
                    $.zui.navtab('reloadForm', that.options.clearQuery, options)
                } else {
                    $.zui.dialog('reloadForm', that.options.clearQuery, options)
                }
            }
        }

        if (!isValid) {
            if ($.fn.validator) {
                $form.isValid(function(v) {
                    if (v) search()
                })
            } else {
                search()
            }
        } else {
            search()
        }
    }

    Zuiajax.prototype.doload = function(option) {
        var that = this, $target = null, options = $.extend({}, typeof option === 'object' && option)

        $.extend(that.options, options)

        if (options.target) {
            $target = options.target
            if($target.toFunc()){
                options.target = $target = $target.toFunc().call(this);
            } else if (!($target instanceof jQuery))
                $target = $($target)
        }

        if (!$target || !$target.length) {
            $.zui.debug('Zuiajax Plugin: \'doload\' method: Not set loaded container, like [data-target].')
            return
        }

        if (!options.url) {
            $.zui.debug('Zuiajax Plugin: \'doload\' method: The url is undefined!')
            return
        } else {
            options.url = decodeURI(options.url).replacePlh()

            if (!options.url.isFinishedTm()) {
                $.zui.alertmsg('error', (options.warn || $.zui.regional.plhmsg))
                $.zui.debug('Zuiajax Plugin: \'doload\' method: The url is incorrect: '+ options.url)
                return
            }

            options.url = encodeURI(options.url)
        }

        $target.removeData('zui.clientPaging').data('options', options)
        that.reloadlayout(options)
    }

    Zuiajax.prototype.refreshlayout = function(target) {
        var that = this, $target

        if (target) {
            $target = target

            if (!($target instanceof jQuery))
                $target = $($target)
        }

        if (!$target || !$target.length) {
            if (autorefreshTimer) clearInterval(autorefreshTimer)
            $.zui.debug('Zuiajax Plugin: \'refreshlayout\' method: No argument, can not refresh DIV.(parameters:[selector/jQuery object/element])')
            return
        }
        if ($target && $target.length) {
            if (!$target.data('options')) {
                $.zui.debug('Zuiajax Plugin: \'refreshlayout\' method: The target(DIV) is not a reload layout!')
                return
            }
            $target.removeData('zui.clientPaging')
            that.reloadlayout($target.data('options'))
        }
    }

    Zuiajax.prototype.reloadlayout = function(option) {
        var $target = null,
            options = $.extend({}, typeof option === 'object' && option),
            arefre  = options && options.autorefresh && (isNaN(String(options.autorefresh)) ? 15 : options.autorefresh)

        if (options.target) {
            $target = options.target

            if (!($target instanceof jQuery))
                $target = $($target)
        }

        if (!$target || !$target.length) {
            if (autorefreshTimer) clearInterval(autorefreshTimer)
            $.zui.debug('Zuiajax Plugin: \'refreshlayout\' method: Not set loaded container, like [data-target].')
            return
        } else {
            if (!$target.data('options')) {
                $.zui.debug('Zuiajax Plugin: \'refreshlayout\' method: This target(DIV) is not initialized!')
                return
            }
            options = $.extend({}, $target.data('options'), options)
        }

        $target
            .addClass('zui-layout')
            .data('options', options)
            .ajaxUrl({ type:options.type, url:options.url, data:options.data, loadingmask:options.loadingmask, callback:function(html) {
                    if ($.zui.ui.clientPaging && $target.data('zui.clientPaging'))
                        $target.pagination('setPagingAndOrderby', $target)
                    if (options.callback)
                        options.callback.apply(this, [$target, html])
                    if (autorefreshTimer)
                        clearInterval(autorefreshTimer)
                    if (arefre)
                        autorefreshTimer = setInterval(function() { $target.zuiajax('refreshlayout', $target) }, arefre * 1000)
                }
            })
    }

    Zuiajax.prototype.refreshdiv = function(divid) {
        if (divid && typeof divid === 'string') {
            var arr = divid.split(',')

            for (var i = 0; i < arr.length; i++) {
                this.refreshlayout('#'+ arr[i])
            }
        }
    }

    Zuiajax.prototype.ajaxdownload = function(option) {
        var that = this, $target, options = $.extend({}, typeof option === 'object' && option)

        options.loadingmask = false

        $.extend(that.options, options)

        if (options.target) {
            $target = options.target

            if (!($target instanceof jQuery))
                $target = $($target)
        }

        if (!$target || !$target.length)
            $target = $.CurrentDialog || $.CurrentNavtab || $('body')

        that.$target = $target

        if (!options.url) {
            $.zui.debug('Zuiajax Plugin: \'ajaxdownload\' method: The url is undefined!')
            return
        } else {
            options.url = decodeURI(options.url).replacePlh($target)

            if (!options.url.isFinishedTm()) {
                $.zui.alertmsg('error', (options.warn || $.zui.regional.plhmsg))
                $.zui.debug('Zuiajax Plugin: \'ajaxdownload\' method: The url is incorrect: '+ options.url)
                return
            }
        }

        var todo = function() {
            var downloadOptions = {}

            downloadOptions.failCallback = function(responseHtml, url) {
                if (responseHtml.trim().startsWith('{')) responseHtml = responseHtml.toObj()
                that.ajaxdone(responseHtml)
                $target.trigger('zui.ajaxError')
            }
            downloadOptions.prepareCallback = function(url) {
                if (options.loadingmask) {
                    $target.trigger('zui.ajaxStart')
                }
            }
            downloadOptions.successCallback = function(url) {
                $target.trigger('zui.ajaxStop')
            }

            if (options.type && !options.httpMethod)
                options.httpMethod = options.type

            $.extend(downloadOptions, options)

            if (!downloadOptions.data) downloadOptions.data = {}
            if (typeof downloadOptions.data.ajaxrequest === 'undefined') downloadOptions.data.ajaxrequest = true

            $.fileDownload(options.url, downloadOptions)
        }

        if (options.confirmMsg) {
            $.zui.alertmsg('confirm', options.confirmMsg, {
                okCall: function() {
                    todo()
                }
            })
        } else {
            todo()
        }
    }

    // Deprecated
    Zuiajax.prototype.doexport = function(options) {
        var that = this, $element = that.$element, $target = options.target ? $(options.target) : null, form

        if (!options.url) {
            $.zui.debug('Error trying to open a ajax link: url is undefined!')
            return
        } else {
            options.url = decodeURI(options.url).replacePlh($element.closest('.unitBox'))

            if (!options.url.isFinishedTm()) {
                $.zui.alertmsg('error', (options.warn || $.zui.regional.plhmsg))
                $.zui.debug('The ajax url is incorrect: '+ options.url)
                return
            }
        }

        var todo = function() {
            if (!$target || !$target.length) {
                if (that.tools.getTarget() == Zuiajax.NAVTAB) {
                    $target = $.CurrentNavtab
                } else {
                    $target = $.CurrentDialog
                }
            }
            form = that.tools.getPagerForm($target)

            if (form) {
                if (!options.data) options.data = {}
                $.extend(options.data, $(form).serializeJson())
            }

            $.fileDownload(options.url, {
                failCallback: function(responseHtml, url) {
                    if (responseHtml.trim().startsWith('{')) responseHtml = responseHtml.toObj()
                    that.ajaxdone(responseHtml)
                },
                data: options.data || {}
            })
        }

        if (options.confirmMsg) {
            $.zui.alertmsg('confirm', options.confirmMsg, {
                okCall: function() {
                    todo()
                }
            })
        } else {
            todo()
        }
    }

    // Deprecated
    Zuiajax.prototype.doexportchecked = function(options) {
        var that = this, $element = that.$element, $target = options.target ? $(options.target) : null, idname

        if (!options.url) {
            $.zui.debug('Error trying to open a export link: url is undefined!')
            return
        } else {
            options.url = decodeURI(options.url).replacePlh($element.closest('.unitBox'))

            if (!options.url.isFinishedTm()) {
                $.zui.alertmsg('error', (options.warn || $.zui.regional.plhmsg))
                $.zui.debug('The ajax url is incorrect: '+ options.url)
                return
            }
        }

        var todo = function() {
            if (!options.group) {
                $.zui.alertmsg('error', options.warn || $.zui.regional.nocheckgroup)
                return
            }
            if (!$target || !$target.length) {
                if (that.tools.getTarget() == Zuiajax.NAVTAB) {
                    $target = $.CurrentNavtab
                } else {
                    $target = $.CurrentDialog
                }
            }

            var ids     = [],
                $checks = $target.find(':checkbox[name='+ options.group +']:checked')

            if (!$checks.length) {
                $.zui.alertmsg('error', $.zui.regional.notchecked)
                return
            }
            $checks.each(function() {
                ids.push($(this).val())
            })

            idname = options.idname || 'ids'
            options.data = options.data || {}
            options.data[idname] = ids.join(',')

            $.fileDownload(options.url, {
                failCallback: function(responseHtml, url) {
                    if (responseHtml.trim().startsWith('{')) responseHtml = responseHtml.toObj()
                    that.ajaxdone(responseHtml)
                },
                data: options.data
            })
        }

        if (options.confirmMsg) {
            $.zui.alertmsg('confirm', options.confirmMsg, {
                okCall: function() {
                    todo()
                }
            })
        } else {
            todo()
        }
    }

    // Deprecated
    Zuiajax.prototype.doajaxchecked = function(options) {
        var that = this, $element = that.$element, $target = options.target ? $(options.target) : null, idname

        options = $.extend({}, Zuiajax.DEFAULTS, typeof options === 'object' && options)
        if (!options.url) {
            $.zui.debug('Error trying to open a del link: url is undefined!')
            return
        } else {
            options.url = decodeURI(options.url).replacePlh($element.closest('.unitBox'))

            if (!options.url.isFinishedTm()) {
                $.zui.alertmsg('error', (options.warn || $.zui.regional.plhmsg))
                $.zui.debug('The ajax url is incorrect: '+ options.url)
                return
            }
        }

        var todo = function() {
            if (!options.group) {
                $.zui.alertmsg('error', options.warn || $.zui.regional.nocheckgroup)
                return
            }
            if (!$target || !$target.length) {
                if (that.tools.getTarget() == Zuiajax.NAVTAB) {
                    $target = $.CurrentNavtab
                } else {
                    $target = $.CurrentDialog
                }
            }

            var ids      = [],
                $checks  = $target.find(':checkbox[name='+ options.group +']:checked'),
                callback = options.callback && options.callback.toFunc()

            if (!$checks.length) {
                $.zui.alertmsg('error', $.zui.regional.notchecked)
                return
            }
            $checks.each(function() {
                ids.push($(this).val())
            })

            idname = options.idname || 'ids'
            options.data = options.data || {}
            options.data[idname] = ids.join(',')

            $element.doAjax({type:options.type, url:options.url, data:options.data, callback:callback ? callback : $.proxy(function(data) {that.ajaxcallback(data)}, that)})
        }

        if (options.confirmMsg) {
            $.zui.alertmsg('confirm', options.confirmMsg, {
                okCall: function() {
                    todo()
                }
            })
        } else {
            todo()
        }
    }

    // ZUIAJAX PLUGIN DEFINITION
    // =======================

    function Plugin(option) {
        var args     = arguments,
            property = option,
            ajax     = 'zui.ajax',
            $body    = $('body')

        return this.each(function () {
            var $this   = $(this),
                options = $.extend({}, Zuiajax.DEFAULTS, typeof option === 'object' && option),
                data    = $this.data(ajax),
                func

            if (!data) {
                data = new Zuiajax(this, options)
            } else {
                if (this === $body[0]) {
                    data = new Zuiajax(this, options)
                } else {
                    $.extend(data.options, typeof option === 'object' && option)
                }
            }

            $this.data(ajax, data)

            if (typeof property === 'string') {
                func = data[property.toLowerCase()]
                if ($.isFunction(func)) {
                    [].shift.apply(args)
                    if (!args) func()
                    else func.apply(data, args)
                }
            }
        })
    }

    var old = $.fn.zuiajax

    $.fn.zuiajax             = Plugin
    $.fn.zuiajax.Constructor = Zuiajax

    // ZUIAJAX NO CONFLICT
    // =================

    $.fn.zuiajax.noConflict = function () {
        $.fn.zuiajax = old
        return this
    }

    // NOT SELECTOR
    // ==============

    $.zui.ajax = function() {
        Plugin.apply($('body'), arguments)
    }

    $(document).on('click.zui.zuiajax.data-api', '[data-toggle="ajaxload"]', function(e) {
        var $this = $(this), data = $this.data(), options = data.options

        if (options) {
            if (typeof options === 'string') options = options.toObj()
            if (typeof options === 'object') {
                delete data.options
                $.extend(data, options)
            }
        }

        if (!data.url) data.url = $this.attr('href')

        Plugin.call($this, 'doload', data)

        e.preventDefault()
    })

    $(document).on($.zui.eventType.initUI, function(e) {
        $(e.target).find('[data-toggle="autoajaxload"]').each(function() {
            var $element = $(this), options = $element.data()

            options.target = this
            Plugin.call($element, 'doload', options)
        })
    })

    $(document).on('click.zui.zuiajax.data-api', '[data-toggle="refreshlayout"]', function(e) {
        var $this = $(this), target = $this.data('target')

        Plugin.call($this, 'refreshlayout', target)

        e.preventDefault()
    })

    $(document).on('click.zui.zuiajax.data-api', '[data-toggle="reloadlayout"]', function(e) {
        var $this = $(this), data = $this.data()

        Plugin.call($this, 'reloadlayout', data)

        e.preventDefault()
    })

    $(document).on('click.zui.zuiajax.data-api', '[data-toggle="doajax"]', function(e) {
        var $this = $(this), data = $this.data(), options = data.options

        if (options) {
            if (typeof options === 'string') options = options.toObj()
            if (typeof options === 'object') {
                delete data.options
                $.extend(data, options)
            }
        }

        if (!data.url) data.url = $this.attr('href')

        Plugin.call($this, 'doajax', data)

        e.preventDefault()
    })

    $(document).on('click.zui.zuiajax.data-api', '[data-toggle="ajaxdownload"]', function(e) {
        var $this = $(this), data = $this.data(), options = data.options

        if (options) {
            if (typeof options === 'string') options = options.toObj()
            if (typeof options === 'object') {
                delete data.options
                $.extend(data, options)
            }
        }
        if (!data.url) data.url = $this.attr('href')

        Plugin.call($this, 'ajaxdownload', data)

        e.preventDefault()
    })

    $(document).on('click.zui.zuiajax.data-api', '[data-toggle="doexport"]', function(e) {
        var $this = $(this), options = $this.data()

        if (!options.url) options.url = $this.attr('href')

        Plugin.call($this, 'doexport', options)

        e.preventDefault()
    })

    $(document).on('click.zui.zuiajax.data-api', '[data-toggle="doexportchecked"]', function(e) {
        var $this = $(this), options = $this.data()

        if (!options.url) options.url = $this.attr('href')

        Plugin.call($this, 'doexportchecked', options)

        e.preventDefault()
    })

    $(document).on('click.zui.zuiajax.data-api', '[data-toggle="doajaxchecked"]', function(e) {
        var $this = $(this), options = $this.data()

        if (!options.url) options.url = $this.attr('href')

        Plugin.call($this, 'doajaxchecked', options)

        e.preventDefault()
    })

}(jQuery);
